﻿using System;
using System.Collections.Generic;
using System.Linq;
using EzDesk.Core.Interface;
using EzDesk.Core.Model;
using EzDesk.Utility;

namespace EzDesk.Core.ServiceImpl.Services
{
    public partial class CoreService: ICoreService
    {
        readonly string MEMBERSTRING_EVERYONE = "everyone";

        #region [ Group Methods ]

        Group ICoreService.CreateGroup(SimpleUser[] users, Group[] groups, string descrition, int type)
        {
            var group = new Group();
            group.Id = Guid.NewGuid();

            List<string> ids = new List<string>();
            ids.Add(users.Join(",", u => u.Id.ToString()));
            ids.AddRange(groups.ToStringArrary(g => g.Id.ToString()));
            group.MemberString = ids.Join("|");

            if (string.IsNullOrEmpty(descrition))
            {
                group.Description = users.Join(";", u => u.UserName) + groups.Join(";", g => g.Description);
            }
            else
            {
                group.Description = descrition;
            }
            group.Type = type;

            _groupRepository.Add(group);
            return group;

        }
        void ICoreService.DeleteGroup(Guid groupId)
        {
            _groupRepository.Delete(groupId);
        }
        void ICoreService.ChangeGroupDescription(Guid groupId, string description)
        {
            var group = _groupRepository.GetById(groupId);
            group.Description = description;
            _groupRepository.Update(group);
        }
        
        IList<Group> ICoreService.GetAllSystemGroups()
        {
            return _groupRepository.GetAll()
                .Where(g => g.Type == 0)
                .ToList();
        }
        public Group GetSystemGroup(string groupName)
        {
            return _groupRepository.GetAll()
                .Where(p => p.MemberString == groupName && p.Type == 0)
                .FirstOrDefault();
        }
        
        Group ICoreService.GetGroupById(Guid groupId)
        {
            return self.GetGroups(
                convertSingleIdToIdCollection(groupId)
                )
                .FirstOrDefault();
        }


        Group ICoreService.GetGroupByName(string groupName)
        {
            return _groupRepository.GetAll()
                .Where(g => g.Name == groupName)
                .SingleOrDefault();
        }

        IList<Group> ICoreService.GetGroups(string groupIdStrs)
        {
            return self.GetGroups(
                convertIdStrsToIdCollection(groupIdStrs)
                );
        }
        IList<Group> ICoreService.GetGroups(Guid[] groupIdCollection)
        {
            IList<Group> groupList = new List<Group>();
            foreach (var gid in groupIdCollection)
            {
                groupList.Add(_groupRepository.GetById(gid));
            }
            return groupList;
        }

        IDictionary<Guid, string> ICoreService.GetChildrenByMemberstring(string memberString)
        {
            Dictionary<Guid, string> result = new Dictionary<Guid, string>();

            // memberstring 是everyone的特殊情况
            if (memberString == MEMBERSTRING_EVERYONE)
            {
                // 添加everyone组
                result.Add(
                    self.GetSystemGroup(MEMBERSTRING_EVERYONE).Id,
                    "group"
                );
            }
            else
            {
                var members = memberString.Split('|');
                if (members.Length > 0)
                {
                    var users = members[0].Split(',');
                    foreach (var user in users)
                    {
                        Guid userId = Guid.Empty;
                        if (Guid.TryParse(user, out userId))
                        {
                            result.Add(userId, "user");
                        }
                    }
                }
                if (members.Length > 1)
                {
                    var groups = members[1].Split(',');
                    foreach (var group in groups)
                    {
                        Guid groupId = Guid.Empty;
                        if (Guid.TryParse(group, out groupId))
                        {
                            result.Add(groupId, "group");
                        }
                    }
                }
            }

            return result;
        }

        IList<SimpleUser> ICoreService.GetAllUsersInGroup(Guid groupId)
        {
            Group group = self.GetGroupById(groupId);
            return self.GetAllUsersByMemberString(group.MemberString);
        }        
        IList<Guid> ICoreService.GetAllUserIdsByMemberString(string memberString)
        {
            return getAllUserIdsByMemberString(memberString);
        }
        IList<SimpleUser> ICoreService.GetAllUsersByMemberString(string memberString)
        {
            return
                self.GetSimpleUserInfos(
                    self.GetAllUserIdsByMemberString(memberString).ToArray()
                    );
        }

        public IList<Group> GetUserInGroups(Guid userId, int groupType = -1)
        {
            IList<Group> result = new List<Group>();
            //todo: 重构 用缓存解决这里的性能问题
            var groups = _groupRepository.GetAll();
            if (groupType >= 0)
            {
                groups = groups.Where(p => p.Type == groupType);
            }
            foreach (var group in groups)
            {
                if (IsMemberstringContainUser(userId, group.MemberString))
                {
                    result.Add(group);
                }
            }
            return result;
        }

        public bool IsUserInGroup(Guid userId, Guid groupId)
        {
            Group group = self.GetGroupById(groupId);
            return IsMemberstringContainUser(userId, group.MemberString);
        }

        private bool IsMemberstringContainUser(Guid userId, string memberstring)
        {
            return self.GetAllUserIdsByMemberString(memberstring).Contains(userId);
        }

        void ICoreService.AddUserInGroup(Guid targetGroupId, Guid userId)
        {
            var group = _groupRepository.GetById(targetGroupId);
            if (String.IsNullOrEmpty(group.MemberString))
            {
                group.MemberString = userId.ToString();
            }
            else
            {
                group.MemberString = String.Format("{0},{1}", userId.ToString(), group.MemberString);
            }
            _groupRepository.Update(group);
        }
        void ICoreService.AddGroupInGroup(Guid targetGroupId, Guid groupId)
        {
            var group = _groupRepository.GetById(targetGroupId);
            group.MemberString = string.Format("{0},{1}", group.MemberString, groupId);
            _groupRepository.Update(group);
        }

        void ICoreService.RemoveUserFromGroup(Guid targetGroupId, Guid userId)
        {
            var group = _groupRepository.GetById(targetGroupId);

            string[] groupIds = group.MemberString.Split('|');
            List<string> userIds = groupIds[0].Split(',').ToList();
            userIds.Remove(userId.ToString());
            groupIds[0] = String.Join(",", userIds.ToArray());
            group.MemberString = string.Join("|", groupIds);

            _groupRepository.Update(group);

        }
        void ICoreService.RemoveGroupFromGroup(Guid targetGroupId, Guid groupId)
        {
            var group = _groupRepository.GetById(targetGroupId);

            List<string> groupIds = group.MemberString.Split('|').ToList();
            groupIds.Remove(groupId.ToString());
            group.MemberString = string.Join("|", groupIds.ToArray());

            _groupRepository.Update(group);
        }

        #endregion


        #region [ private methods ]
        
        IList<Guid> getAllUserIdsByMemberString(string memberString)
        {
            IList<Guid> userIds = new List<Guid>();
            if (string.IsNullOrEmpty(memberString))return userIds;
            
            if (memberString == MEMBERSTRING_EVERYONE)
            {
                // 所有人
                userIds = _userRepository.GetAll()
                    .Select(p => p.Id)
                    .ToArray();
            }
            else
            {
                string[] strs = memberString.Split('|');

                if (strs.Length > 0)
                {
                    if (!string.IsNullOrEmpty(strs[0]))
                    {
                        // memberstring中的userIds数据
                        userIds = strs[0]
                            .Split(',')
                            .Select(p => new Guid(p))
                            .ToList();
                    }
                }

                if (strs.Length > 1)
                {
                    // 取得memberstring中包含的groups
                    var groups = self.GetGroups(strs[1]);

                    foreach (var group in groups)
                    {
                        userIds = userIds.Union(
                            getAllUserIdsByMemberString(group.MemberString)
                            )
                            .ToList();
                    }
                }
            }
            return userIds.Distinct().ToList();
        }
        #endregion



    }
}

    
